package com.tfswx.jkgl.designer.datasource;


import com.tfswx.jkgl.core.exception.AppException;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.mapping.VendorDatabaseIdProvider;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 核心方法 ：继承AbstractRoutingDataSource 类，将数据源交给AbstractRoutingDataSource进行注入使用
 *
 * @author ricky
 * @date 2021/12/14
 */
@Slf4j
public class DynamicDataSource extends AbstractRoutingDataSource {
    public Map<Object, Object> myMap = null;
    public Map<Object, DataSource> sourceMap = null;
    public Map<Object, String> nameMap = null;
    private static DatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
    private static VendorDatabaseIdProvider vendorDatabaseIdProvider;

    static {
        Properties p = new Properties();
        p.setProperty("Oracle", "oracle");
        p.setProperty("MySQL", "mysql");
        p.setProperty("SQLite", "sqlite");
        p.setProperty("PostgreSQL", "postgresql");
        p.setProperty("DM DBMS", "dm");
        p.setProperty("SQL Server", "sqlserver");
        databaseIdProvider.setProperties(p);
        vendorDatabaseIdProvider = new VendorDatabaseIdProvider();
    }

    public DynamicDataSource() {
        myMap = new HashMap<>();
        sourceMap = new HashMap<>();
        nameMap = new HashMap<>();
    }


    @Override
    protected Object determineCurrentLookupKey() {
        /*
         * DynamicDataSourceContextHolder代码中使用setDataSourceType
         * 设置当前的数据源，在路由类中使用getDataSourceType进行获取，
         *  交给AbstractRoutingDataSource进行注入使用。
         */
        String dataSourceType = DynamicDataSourceContextHolder.getDataSourceType();
        DataSource dataSource = sourceMap.get(dataSourceType);
        if (dataSource == null) {
            throw new AppException("未配置数据库或数据库加载失败！");
        }
        String databaseId = "";
        try {
            databaseId = databaseIdProvider.getDatabaseId(dataSource);
            if (databaseId == null) {
                databaseId = vendorDatabaseIdProvider.getDatabaseId(dataSource);
            }
        } catch (Exception e) {
            log.error("读取数据库类型失败", e);
        }
        String s = nameMap.get(dataSourceType);
        log.info("\n数据源: {}，名称: {}，标识：{}", dataSourceType, s, databaseId);

        return dataSourceType;
    }
}
